<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        /*
          1. promise是什么?
             是一个封装异步操作的容器 
          2. promise用于解决什么问题?
             在之前的开发中, 一些异步操作经常采用回调函数来完成
             如果回调嵌套回调, 业务层级一深, 代码就非常难以维护 (回调地狱)
             promise就是专门解决回调地狱的一种方案
          3. promise怎么操作?
             let p = new Promise((resolve, reject)=>{
                 // 异步操作的结果要么成功, 要么失败
                 // promise内部有3中状态: pending  fulfilled  rejected (状态不可逆)
                 resolve(成功的结果) 成功的时候调用该函数, pending => fulfilled
                 reject(失败的结果)  时报的时候调用该函数, pending => rejected
             })
             外部通过链式的方式调用
             p.then((res)=>{
                // 这个函数在状态为fulfilled时候被调用
                // 处理成功的结果
             }).catch((error)=>{
                 // 这个函数在状态为rejected时候被调用
                // 处理失败的结果
             })
        */

        /*
          需求:
          // 需求1：开一个延时器 setTimeout，在延迟器结束后， 做某件事： alert 一个延时器结束了
          // 需求2：要做的事情，不希望写死，第一次 alert 一个zs， 第二次 console 一个ls
          // 需求3：希望是等待做完第一件事情之后，再等待做第二件事   
        */
        //  function doFn(callback){
        //      setTimeout(()=>{
        //         // 延迟2s后做某个操作, 但操作不固定
        //         callback()
        //      }, 2000)
        //  }

        // 2秒后弹窗
        //  doFn(()=>{
        //      alert('弹个窗')
        //  })

        // 2秒后打印
        //  doFn(()=>{
        //      console.log('打个印')
        //  })

        // 需求: 两秒后输出"张三", 再过两秒后输出"李四", 再过两秒后输出"王五"
        // 1. 回调函数方式
        //  function doFn(callback){
        //      setTimeout(()=>{
        //         // 延迟2s后做某个操作, 但操作不固定
        //         callback()
        //      }, 2000)
        //  }

        //  doFn(()=>{
        //      console.log('张三')
        //      doFn(()=>{
        //          console.log('李四')
        //          doFn(()=>{
        //              console.log('王五')
        //          })
        //      })
        //  })

        // 2. promise方式
        function doFn(){
            return new Promise((resolve, reject)=>{
                setTimeout(()=>{
                    resolve()
                }, 2000)
            })
        }

        // doFn().then(()=>{
        //     console.log('张三')
        //     return doFn()
        // }).then(()=>{
        //     console.log('李四')
        //     return doFn()
        // }).then(()=>{
        //     console.log('王五')
        // })

        // 用async和await简化
        // 思维: 用同步的方式写异步代码, 本质上还是对.then()调用方式的简化
        async function fn(){
            await doFn()
            console.log('张三')

            await doFn()
            console.log('李四')

            await doFn()
            console.log('王五')
        }    
        fn()

        /* 
          总结:
          如果业务中需要在异步操作完成后去做某件事情
          1) 回调函数 将要做的操作封装成一个函数传入, 在内部执行该函数
          2) promise 把异步操作放在一个容器里面, 成功则resolve(), 失败则reject()
             p.then(()=>{}).catch(()=>{}) 或者 async/await

          axios库就是基于promise包装了一个XMLHttpRequest实例
          new Promise((resolve, reject)=>{
               new XMLHttpRequest()
               ....
          })
          
          axios({}).then().catch() 或者 async/await
        */
    </script>
</body>

</html>